using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Oops.Xna.Framework
{
	public class Sphere
	{
		private VertexPositionNormalTexture[] vertices;
		private int[] indices;

		public Sphere(int ringCount, int segmentCount)
		{
			//int ringCount = 10;
			//int segmentCount = 16;

			this.vertices = new VertexPositionNormalTexture[(ringCount + 1) * (segmentCount + 1)];
			this.indices = new int[6 * ringCount * (segmentCount + 1)];

			float deltaRingAngle = (float)Math.PI / ringCount;
			float deltaSegmentAngle = 2.0f * (float)Math.PI / segmentCount;

			// Generate the group of rings for the sphere
			int vertexIndex = 0;
			int indexIndex = 0;
			for (int i = 0; i <= ringCount; i++)
			{
				float ring = (float)Math.Sin(i * deltaRingAngle);
				float y = (float)Math.Cos(i * deltaRingAngle);

				// Generate the group of segments for the current ring
				for (int j = 0; j <= segmentCount; j++)
				{
					float x = ring * (float)Math.Sin(j * deltaSegmentAngle);
					float z = ring * (float)Math.Cos(j * deltaSegmentAngle);

					// Add one vertex to the strip which makes up the sphere
					Vector3 position = new Vector3(x, y, z);
					Vector3 normal = Vector3.Normalize(position);
					Vector2 textureCoordinate = new Vector2((float)j / segmentCount, (float)i / ringCount);

					this.vertices[vertexIndex] = new VertexPositionNormalTexture(position, normal, textureCoordinate);

					if (i != ringCount)
					{
						// each vertex (except the last) has six indices pointing to it
						this.indices[indexIndex++] = vertexIndex + segmentCount;
						this.indices[indexIndex++] = vertexIndex;
						this.indices[indexIndex++] = vertexIndex + segmentCount + 1;
						this.indices[indexIndex++] = vertexIndex;
						this.indices[indexIndex++] = vertexIndex + 1;
						this.indices[indexIndex++] = vertexIndex + segmentCount + 1;
					}

					vertexIndex++;
				}
			}
		}

		public VertexPositionNormalTexture[] Vertices
		{
			get { return this.vertices; }
		}

		public int[] Indices
		{
			get { return this.indices; }
		}
	}
}
